home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / game / think / newmasterm_src.lha / newmastermind / panelgadget.c < prev    next >
C/C++ Source or Header  |  2000-11-08  |  6KB  |  251 lines

  1. /*
  2.  * panelgadget.c
  3.  * =============
  4.  * The panel gadget.
  5.  *
  6.  * Copyright (C) 1994-2000 Håkan L. Younes (lorens@hem.passagen.se)
  7.  */
  8.  
  9. #include <intuition/gadgetclass.h>
  10. #include <libraries/gadtools.h>
  11.  
  12. #include <clib/alib_protos.h>
  13. #include <proto/intuition.h>
  14. #include <proto/graphics.h>
  15. #include <proto/utility.h>
  16.  
  17. #include "panelgadget.h"
  18. #include "markers.h"
  19.  
  20.  
  21. typedef struct {
  22.   UBYTE numColors;
  23.   UBYTE activeColor;
  24.   UBYTE nextColor;
  25. } PanelClassData;
  26.  
  27.  
  28. static BOOL PanelNew(Class *cl, struct Gadget *obj, struct opSet *msg) {
  29.   PanelClassData *data = INST_DATA(cl, obj);
  30.   struct TagItem *ti, *tstate = msg->ops_AttrList;
  31.  
  32.   data->numColors = 6;
  33.   data->activeColor = data->nextColor = 0;
  34.   while ((ti = NextTagItem(&tstate)) != NULL) {
  35.     switch (ti->ti_Tag) {
  36.     case PANEL_NumColors:
  37.       data->numColors = ti->ti_Data;
  38.       break;
  39.     case PANEL_ActiveColor:
  40.       data->activeColor = ti->ti_Data;
  41.       break;
  42.     }
  43.   }
  44.   obj->Width = 8 * (LMARKER_W + INTERWIDTH) - INTERWIDTH;
  45.   obj->Height = LMARKER_H;
  46.  
  47.   return TRUE;
  48. }
  49.  
  50.  
  51. static VOID PanelSet(Class *cl, struct Gadget *obj, struct opSet *msg) {
  52.   PanelClassData *data = INST_DATA(cl, obj);
  53.   struct TagItem *ti, *tstate = msg->ops_AttrList;
  54.   struct RastPort *rp;
  55.  
  56.   while ((ti = NextTagItem(&tstate)) != NULL) {
  57.     switch (ti->ti_Tag) {
  58.     case PANEL_NumColors:
  59.       rp = ObtainGIRPort(msg->ops_GInfo);
  60.       if (rp != NULL) {
  61.     if (ti->ti_Data < data->numColors) {
  62.       EraseRect(rp,
  63.             (LONG)obj->LeftEdge +
  64.             ti->ti_Data * (LMARKER_W + INTERWIDTH),
  65.             (LONG)obj->TopEdge,
  66.             (LONG)obj->LeftEdge + obj->Width - 1,
  67.             (LONG)obj->TopEdge + obj->Height - 1);
  68.     }
  69.     if (ti->ti_Data != data->numColors) {
  70.       data->numColors = ti->ti_Data;
  71.       data->activeColor = 0;
  72.       DoMethod((Object *)obj,
  73.            GM_RENDER, msg->ops_GInfo, rp, GREDRAW_REDRAW);
  74.     } else {
  75.       data->nextColor = 0;
  76.       DoMethod((Object *)obj,
  77.            GM_RENDER, msg->ops_GInfo, rp, GREDRAW_UPDATE);
  78.       data->activeColor = 0;
  79.     }
  80.     ReleaseGIRPort(rp);
  81.       } else {
  82.     data->numColors = ti->ti_Data;
  83.     data->activeColor = 0;
  84.       }
  85.       break;
  86.     case PANEL_ActiveColor:
  87.       if (ti->ti_Data != data->activeColor) {
  88.     data->nextColor = ti->ti_Data;
  89.     rp = ObtainGIRPort(msg->ops_GInfo);
  90.     if (rp != NULL) {
  91.       DoMethod((Object *)obj,
  92.            GM_RENDER, msg->ops_GInfo, rp, GREDRAW_UPDATE);
  93.       ReleaseGIRPort(rp);
  94.     }
  95.     data->activeColor = data->nextColor;
  96.       }
  97.       break;
  98.     }
  99.   }
  100. }
  101.  
  102.  
  103. static BOOL PanelGet(Class *cl, struct Gadget *obj, struct opGet *msg) {
  104.   PanelClassData *data = INST_DATA(cl, obj);
  105.  
  106.   switch (msg->opg_AttrID) {
  107.   case PANEL_NumColors:
  108.     *msg->opg_Storage = (ULONG)data->numColors;
  109.     break;
  110.   case PANEL_ActiveColor:
  111.     *msg->opg_Storage = (ULONG)data->activeColor;
  112.     break;
  113.   default:
  114.     return FALSE;
  115.   }
  116.  
  117.   return TRUE;
  118. }
  119.  
  120.  
  121. static VOID PanelRender(Class *cl, struct Gadget *obj, struct gpRender *msg) {
  122.   PanelClassData *data = INST_DATA(cl, obj);
  123.  
  124.   if (msg->gpr_Redraw == GREDRAW_REDRAW) {
  125.     UBYTE i;
  126.  
  127.     for (i = 0; i < data->numColors; i++) {
  128.       DrawLargeMarker(msg->gpr_RPort, msg->gpr_GInfo->gi_DrInfo,
  129.               (LONG)obj->LeftEdge + i * (LMARKER_W + INTERWIDTH),
  130.               (LONG)obj->TopEdge + (obj->Height - LMARKER_H) / 2,
  131.               ((i + 1 == data->activeColor) ? 0 : i + 1));
  132.     }
  133.   } else { /* gpr_Redraw == GREDRAW_UPDATE */
  134.     if (data->activeColor != 0) {
  135.       DrawLargeMarker(msg->gpr_RPort, msg->gpr_GInfo->gi_DrInfo,
  136.               (LONG)obj->LeftEdge +
  137.               (data->activeColor - 1) * (LMARKER_W + INTERWIDTH),
  138.               (LONG)obj->TopEdge + (obj->Height - LMARKER_H) / 2,
  139.               data->activeColor);
  140.     }
  141.     if (data->nextColor != 0) {
  142.       DrawLargeMarker(msg->gpr_RPort, msg->gpr_GInfo->gi_DrInfo,
  143.               (LONG)obj->LeftEdge +
  144.               (data->nextColor - 1) * (LMARKER_W + INTERWIDTH),
  145.               (LONG)obj->TopEdge + (obj->Height - LMARKER_H) / 2,
  146.               0);
  147.     }
  148.   }
  149. }
  150.  
  151.  
  152. static ULONG PanelHitTest(Class *cl, struct Gadget *obj,
  153.               struct gpHitTest *msg) {
  154.   PanelClassData *data = INST_DATA(cl, obj);
  155.   WORD x = msg->gpht_Mouse.X;
  156.   WORD y = msg->gpht_Mouse.Y;
  157.   WORD d;
  158.  
  159.   d = (obj->Height - LMARKER_H) / 2;
  160.   if (y < d || y >= d + LMARKER_H) {
  161.     return 0;
  162.   }
  163.   d = x / (LMARKER_W + INTERWIDTH);
  164.   if (d >= data->numColors || x - d * (LMARKER_W + INTERWIDTH) >= LMARKER_W) {
  165.     return 0;
  166.   }
  167.  
  168.   return GMR_GADGETHIT;
  169. }
  170.  
  171.  
  172. static ULONG PanelGoActive(Class *cl, struct Gadget *obj,
  173.                struct gpInput *msg) {
  174.   PanelClassData *data = INST_DATA(cl, obj);
  175.  
  176.   if (msg->gpi_IEvent != NULL) {
  177.     data->nextColor = msg->gpi_Mouse.X / (LMARKER_W + INTERWIDTH) + 1;
  178.     if (data->nextColor != data->activeColor) {
  179.       struct RastPort *rp;
  180.  
  181.       rp = ObtainGIRPort(msg->gpi_GInfo);
  182.       if (rp != NULL) {
  183.     DoMethod((Object *)obj,
  184.          GM_RENDER, msg->gpi_GInfo, rp, GREDRAW_UPDATE);
  185.     ReleaseGIRPort(rp);
  186.       }
  187.       data->activeColor = data->nextColor;
  188.     }
  189.   }
  190.  
  191.   return GMR_NOREUSE;
  192. }
  193.  
  194.  
  195. static ULONG __saveds __asm PanelClassDispatch(register __a0 Class *cl,
  196.                            register __a2 Object *obj,
  197.                            register __a1 Msg msg) {
  198.   ULONG result = 0;
  199.  
  200.   switch (msg->MethodID) {
  201.   case OM_NEW:
  202.     result = DoSuperMethodA(cl, obj, msg);
  203.     if (result != NULL) {
  204.       if (!PanelNew(cl, (struct Gadget *)result, (struct opSet *)msg)) {
  205.     DoMethod((Object *)result, OM_DISPOSE);
  206.     result = NULL;
  207.       }
  208.     }
  209.     break;
  210.   case OM_SET:
  211.     DoSuperMethodA(cl, obj, msg);
  212.     PanelSet(cl, (struct Gadget *)obj, (struct opSet *)msg);
  213.     break;
  214.   case OM_GET:
  215.     if (PanelGet(cl, (struct Gadget *)obj, (struct opGet *)msg)) {
  216.       result = 1;
  217.     } else {
  218.       result = DoSuperMethodA(cl, obj, msg);
  219.     }
  220.     break;
  221.   case GM_RENDER:
  222.     PanelRender(cl, (struct Gadget *)obj, (struct gpRender *)msg);
  223.     break;
  224.   case GM_HITTEST:
  225.     result = PanelHitTest(cl, (struct Gadget *)obj, (struct gpHitTest *)msg);
  226.     break;
  227.   case GM_GOACTIVE:
  228.     result = PanelGoActive(cl, (struct Gadget *)obj, (struct gpInput *)msg);
  229.     break;
  230.   default:
  231.     result = DoSuperMethodA(cl, obj, msg);
  232.     break;
  233.   }
  234.  
  235.   return result;
  236. }
  237.  
  238.  
  239. Class *CreatePanelClass(VOID) {
  240.   Class *cl;
  241.  
  242.   cl = MakeClass(NULL, "gadgetclass", NULL, sizeof(PanelClassData), 0);
  243.   if (cl != NULL) {
  244.     cl->cl_Dispatcher.h_SubEntry = NULL;
  245.     cl->cl_Dispatcher.h_Entry = (HOOKFUNC)PanelClassDispatch;
  246.     cl->cl_Dispatcher.h_Data = NULL;
  247.   }
  248.  
  249.   return cl;
  250. }
  251.